namespace SharpTalk.Client.WpfApplication.ViewModels
{
    using System;
    using System.Globalization;
    using System.Linq;
    using Services;
    using Views;
    using System.Diagnostics;

    public sealed class SettingsViewModel : ViewModelBase<ISettingsView>
    {
        private const int MIN_PORT = 5000;
        private const int MAX_PORT = 65534;

        private bool _needRestart;
        private Uri _uri;
        private readonly CultureInfo[] _cultures = null;
        private CultureInfo _selectedCulture = null;

        public SettingsViewModel(ISettingsView view) 
            : base(view)
        {
            view.DataContext = this;
            View.SetIcon(Helpers.LoadImage("settings_16.png"));
        }

        public Uri LocalServiceUri
        {
            get
            {
                return _uri ?? (Uri.TryCreate(Properties.Settings.Default.LocalServiceUri, UriKind.Absolute, out _uri) ? _uri : null);
            }
        }
        
        public string LocalServiceUriHost
        {
            get
            {
                return LocalServiceUri == null ? null : LocalServiceUri.Host;
            }
        }

        public int LocalServiceUriPort
        {
            get
            {
                return  LocalServiceUri == null ? 0 : LocalServiceUri.Port;
            }
            set
            {
                if (value < MIN_PORT || value > MAX_PORT) return;
               
                try
                {
                    var b = new UriBuilder(LocalServiceUri) {Port = value};
                    _uri = b.Uri;
                    Properties.Settings.Default.LocalServiceUri = _uri.ToString();
                }
                catch (ArgumentOutOfRangeException exp)
                {
                    DisplayMessageService.ShowMessage((WindowBase) View, exp.Message, true, false);
                }
            }
        }

        public string Server
        {
            get { return Properties.Settings.Default.ServerAddress; }
        }

        public int MaximumMessageCount
        {
            get { return Properties.Settings.Default.MaximumMessages; }
            set { Properties.Settings.Default.MaximumMessages = value; }
        }

        public bool SaveMessages
        {
            get { return Properties.Settings.Default.SaveMessages; }
            set { Properties.Settings.Default.SaveMessages = value; }
        }

        /// <summary>
        /// Obtains all installed neutral cultures without the invariant one
        /// </summary>
        public CultureInfo[] Cultures
        {
            get { return _cultures ?? CultureInfo.GetCultures(CultureTypes.NeutralCultures).Where(c=> !string.IsNullOrEmpty(c.Name)).ToArray(); }
        }

        /// <summary>
        /// Obtains or defines the UI culture
        /// </summary>
        public CultureInfo SelectedCulture
        {
            get { return _selectedCulture ??  CultureInfo.CurrentUICulture; }
            set
            {
                if(!string.IsNullOrEmpty(value.Name))
                {
                    _selectedCulture = value;
                    Properties.Settings.Default.Culture = value.Name;
                    _needRestart = !Equals(CultureInfo.CurrentUICulture,value );
                    NotifyPropertyChange(()=>NeedRestart);
                }
            }
        }

        /// <summary>
        /// Determines if the application needs to restart to apply changes
        /// </summary>
        public bool NeedRestart
        {
            get { return _needRestart; }
        }
        /// <summary>
        /// 
        /// </summary>
        public string[] TraceLevels
        {
            get { return Enum.GetNames(typeof(SourceLevels)); }
        }
        /// <summary>
        /// 
        /// </summary>
        public string SelectedTraceLevel
        {
            get { return Properties.Settings.Default.DiagnosticTraceLevel; }
            set { Properties.Settings.Default.DiagnosticTraceLevel = value; }
        }
    }
}